package com.lijinjiang.component;

import com.lijinjiang.constant.Colors;
import com.lijinjiang.constant.Icons;
import com.lijinjiang.listener.ClickTimeLabelListener;
import com.lijinjiang.listener.ClickTopButtonListener;
import com.lijinjiang.listener.ClickTopLabelListener;
import com.lijinjiang.mode.PickerMode;
import com.lijinjiang.model.DateModel;
import com.lijinjiang.model.LocalDateModel;
import com.lijinjiang.model.LocalDateTimeModel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Timestamp;

/**
 * @Description 日期面板
 * @Author lijinjiang
 * @Date 2024-12-30 10:52
 */
public class JDatePanel extends JPanel {

    private final PickerMode pickerMode;

    public PickerMode getPickerMode() {
        return pickerMode;
    }

    private final DateModel<?> dateModel;

    public DateModel<?> getDateModel() {
        return dateModel;
    }

    private final int width = 250;//面板宽度

    public int getWidth() {
        return width;
    }

    private int height = 260;//面板高度

    public int getHeight() {
        return height;
    }

    private JPanel topPanel;//顶部面板，包含年月和操作年月按钮
    private JPanel topLeftPanel;//顶部左部面板，一般有上一年，上一月等
    private JButton superPreviousButton;//超级上一个，一般有上一年或上十年

    public JButton getSuperPreviousButton() {
        return superPreviousButton;
    }

    private JButton previousButton;//上一个按钮，一般是上一月

    public JButton getPreviousButton() {
        return previousButton;
    }

    private JLabel yearLabel;//年度标签

    public JLabel getYearLabel() {
        return yearLabel;
    }

    private JLabel monthLabel;//月份标签

    public JLabel getMonthLabel() {
        return monthLabel;
    }

    private JPanel topCenterPanel;//顶部中间面板，一般有选择年面板和选择月面板

    public JPanel getTopCenterPanel() {
        return topCenterPanel;
    }

    private JPanel topRightPanel;//顶部右部面板，一般有下一年，下一月等
    private JButton superNextButton;//超级下一个按钮，一般有下一年或下十年

    public JButton getSuperNextButton() {
        return superNextButton;
    }

    private JButton nextButton;//下一个按钮，一般有下一月

    public JButton getNextButton() {
        return nextButton;
    }

    private SelectDatePanel selectDatePanel;//选择年度面板

    public SelectDatePanel getSelectDatePanel() {
        return selectDatePanel;
    }

    private JPanel bottomPanel;//顶部面板

    private JPanel bottomLeftPanel;//底部左部面板
    private JPanel bottomRightPanel;//底部右部面板
    private JLabel hourLabel;//时标签

    public JLabel getHourLabel() {
        return hourLabel;
    }

    private JLabel minuteLabel;//分标签

    public JLabel getMinuteLabel() {
        return minuteLabel;
    }

    private JLabel secondLabel;//秒标签

    public JLabel getSecondLabel() {
        return secondLabel;
    }

    private JButton confirmBtn;//确认按钮

    public JDatePanel(PickerMode pickerMode) {
        this(pickerMode, createModel(pickerMode));
    }

    public JDatePanel(PickerMode pickerMode, Object value) {
        this(pickerMode, createModelFromValue(value));
    }

    /*创建一个日期模型*/
    private static DateModel<?> createModel(PickerMode pickerMode) {
        LocalDateTimeModel localDateTimeModel = new LocalDateTimeModel();
        if (pickerMode == PickerMode.MINUTE_10 || pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30) {
            localDateTimeModel.setMinute(0);//如果设置了分钟限制，将分钟默认为0
        }
        return localDateTimeModel;
    }

    private static DateModel<?> createModelFromValue(Object value) {
        if (value instanceof java.time.LocalDate) {
            return new LocalDateModel((java.time.LocalDate) value);
        }
        if (value instanceof java.time.LocalDateTime) {
            return new LocalDateTimeModel((java.time.LocalDateTime) value);
        }
        if (value instanceof Timestamp) {
            return new LocalDateTimeModel(((Timestamp) value).toLocalDateTime());
        }
        throw new IllegalArgumentException("不能从初始值对象构造任何模型");
    }

    public JDatePanel(PickerMode pickerMode, DateModel<?> dateModel) {
        this.pickerMode = pickerMode;
        this.dateModel = dateModel;
        initSuperPreviousButton();//初始化超级上一个按钮
        initPreviousButton();//初始化上一个按钮
        initTopLeftPanel();//初始化顶部左部面板
        initYearLabel();//初始化年度标签
        initMonthLabel();//初始化月份标签
        initTopCenterPanel();//初始化顶部中间面板
        initNextButton();//初始化下一个按钮
        initSuperNextButton();//初始化超级下一个按钮
        initTopRightPanel();//初始化顶部右部面板
        initTopPanel();//初始化顶部面板
        initSelectDatePanel();//初始化选择日期面板
        if (pickerMode == PickerMode.HOUR || pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 || pickerMode == PickerMode.MINUTE_15 ||
                pickerMode == PickerMode.MINUTE_30 || pickerMode == PickerMode.SECOND) {
            initBottomPanel();//初始化底部面板
        }
        initPanel();
    }

    //初始化超级上一个按钮
    private void initSuperPreviousButton() {
        if (superPreviousButton == null) {
            superPreviousButton = new JButton();
            superPreviousButton.setIcon(Icons.getSuperPreviousIconEnabled());
            superPreviousButton.setDisabledIcon(Icons.getSuperPreviousIconDisabled());
            superPreviousButton.setText("");
            superPreviousButton.setPreferredSize(new Dimension(25, 25));
            superPreviousButton.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
            superPreviousButton.setFocusable(false);
            superPreviousButton.setOpaque(true);
            superPreviousButton.addMouseListener(new ClickTopButtonListener(this));//添加监听
        }
    }

    //初始化上一个按钮
    private void initPreviousButton() {
        if (previousButton == null) {
            previousButton = new JButton();
            previousButton.setIcon(Icons.getPreviousIconEnabled());
            previousButton.setDisabledIcon(Icons.getPreviousIconDisabled());
            previousButton.setText("");
            previousButton.setPreferredSize(new Dimension(20, 25));
            previousButton.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
            previousButton.setFocusable(false);
            previousButton.setOpaque(true);
            previousButton.addMouseListener(new ClickTopButtonListener(this));//添加监听
        }
    }

    //创建顶部左部面板
    private void initTopLeftPanel() {
        if (topLeftPanel == null) {
            topLeftPanel = new JPanel();
            GridLayout layout = new GridLayout(1, 2);
            layout.setHgap(3);
            topLeftPanel.setLayout(layout);
            topLeftPanel.setName("");
            topLeftPanel.setOpaque(false);
            if (pickerMode == PickerMode.YEAR || pickerMode == PickerMode.MONTH) {
                topLeftPanel.add(superPreviousButton);
            } else if (pickerMode == PickerMode.DAY || pickerMode == PickerMode.HOUR || pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 ||
                    pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30 || pickerMode == PickerMode.SECOND) {
                topLeftPanel.add(superPreviousButton);
                topLeftPanel.add(previousButton);
            }
        }
    }

    //初始化年度标签
    private void initYearLabel() {
        if (yearLabel == null) {
            yearLabel = new JLabel();
            yearLabel.setFont(new Font("宋体", Font.PLAIN, 15));
            yearLabel.setHorizontalAlignment(SwingConstants.CENTER);
            yearLabel.addMouseListener(new ClickTopLabelListener(this));
        }
    }

    //初始化月份标签
    private void initMonthLabel() {
        if (monthLabel == null) {
            monthLabel = new JLabel();
            monthLabel.setFont(new Font("宋体", Font.PLAIN, 15));
            monthLabel.setHorizontalAlignment(SwingConstants.CENTER);
            monthLabel.addMouseListener(new ClickTopLabelListener(this));
        }
    }

    //初始化顶部中间面板
    private void initTopCenterPanel() {
        if (topCenterPanel == null) {
            topCenterPanel = new JPanel();
            topCenterPanel.setOpaque(false);
            topCenterPanel.setBorder(BorderFactory.createEmptyBorder(-3, 5, -3, 5));
            if (pickerMode == PickerMode.YEAR || pickerMode == PickerMode.MONTH) {
                topCenterPanel.add(yearLabel);
            } else if (pickerMode == PickerMode.DAY || pickerMode == PickerMode.HOUR || pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 ||
                    pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30 || pickerMode == PickerMode.SECOND) {
                topCenterPanel.add(yearLabel);
                topCenterPanel.add(monthLabel);
            }
        }
    }

    //初始化下一个按钮
    private void initNextButton() {
        if (nextButton == null) {
            nextButton = new JButton();
            nextButton.setIcon(Icons.getNextIconEnabled());
            nextButton.setDisabledIcon(Icons.getNextIconDisabled());
            nextButton.setText("");
            nextButton.setPreferredSize(new Dimension(20, 25));
            nextButton.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
            nextButton.setFocusable(false);
            nextButton.setOpaque(true);
            nextButton.addMouseListener(new ClickTopButtonListener(this));//添加监听
        }
    }

    //初始化超级下一个图标
    private void initSuperNextButton() {
        if (superNextButton == null) {
            superNextButton = new JButton();
            superNextButton.setIcon(Icons.getSuperNextIconEnabled());
            superNextButton.setDisabledIcon(Icons.getSuperNextIconDisabled());
            superNextButton.setText("");
            superNextButton.setPreferredSize(new Dimension(25, 25));
            superNextButton.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
            superNextButton.setFocusable(false);
            superNextButton.setOpaque(true);
            superNextButton.addMouseListener(new ClickTopButtonListener(this));//添加监听
        }
    }

    //初始化顶部右部面板
    private void initTopRightPanel() {
        if (topRightPanel == null) {
            topRightPanel = new JPanel();
            GridLayout layout = new GridLayout(1, 2);
            layout.setHgap(3);
            topRightPanel.setLayout(layout);
            topRightPanel.setName("");
            topRightPanel.setOpaque(false);
            if (pickerMode == PickerMode.YEAR || pickerMode == PickerMode.MONTH) {
                topRightPanel.add(superNextButton);
            } else if (pickerMode == PickerMode.DAY || pickerMode == PickerMode.HOUR || pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 ||
                    pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30 || pickerMode == PickerMode.SECOND) {
                topRightPanel.add(nextButton);
                topRightPanel.add(superNextButton);
            }
        }
    }

    //初始化顶部面板
    private void initTopPanel() {
        if (topPanel == null) {
            topPanel = new JPanel();
            topPanel.setLayout(new BorderLayout());
            topPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
            topPanel.setBackground(Colors.BG_TOP_PANEL);
            topPanel.add(topLeftPanel, BorderLayout.WEST);
            topPanel.add(topCenterPanel, BorderLayout.CENTER);
            topPanel.add(topRightPanel, BorderLayout.EAST);
        }
    }

    //初始化选择年面板
    private void initSelectDatePanel() {
        if (selectDatePanel == null) {
            selectDatePanel = new SelectDatePanel(this);
        }
    }

    //初始化底部面板
    private void initBottomPanel() {
        if (bottomPanel == null) {
            bottomPanel = new JPanel();
            bottomPanel.setLayout(new BorderLayout());
        }
        bottomPanel.setBackground(Colors.BG_TIME_PANEL);
        height = 278;//加大日历面板高度
        Font font = new Font("宋体", Font.PLAIN, 15);
        Dimension dimension = new Dimension(50, 28);
        bottomLeftPanel = new JPanel();
        bottomLeftPanel.setOpaque(false);//设置为透明的
        bottomLeftPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));

        initHourLabel(dimension, font);

        if (pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 || pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30
                || pickerMode == PickerMode.SECOND) {
            initMinuteLabel(dimension, font);
        }
        if (pickerMode == PickerMode.SECOND) {
            initSecondLabel(dimension, font);
        }
        bottomLeftPanel.setPreferredSize(new Dimension(150, 28));

        bottomRightPanel = new JPanel();
        bottomRightPanel.setOpaque(false);//设置为透明的
        confirmBtn = new JButton("确认");
        confirmBtn.setIcon(Icons.getConfirmIcon());
        confirmBtn.setText("");
        confirmBtn.setPreferredSize(new Dimension(26, 26));
        confirmBtn.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        confirmBtn.setFocusable(false);
        confirmBtn.setOpaque(true);
        confirmBtn.addMouseListener(new MouseAdapter() {
            @Override public void mousePressed(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    dateModel.setSelected(true);//确认选择时间
                }
            }
        });
        bottomRightPanel.setBorder(BorderFactory.createEmptyBorder(-3, 0, -3, -3));
        bottomRightPanel.add(confirmBtn);

        bottomPanel.add(bottomLeftPanel, BorderLayout.WEST);
        bottomPanel.add(bottomRightPanel, BorderLayout.EAST);
    }

    public void initHourLabel(Dimension dimension, Font font) {
        hourLabel = new JLabel();
        hourLabel.setText(String.format("%02d", dateModel.getHour()) + " 时");
        hourLabel.setPreferredSize(dimension);
        hourLabel.setHorizontalAlignment(JLabel.CENTER);
        hourLabel.setFont(font);
        bottomLeftPanel.add(hourLabel);
        hourLabel.addMouseListener(new ClickTimeLabelListener(this));
    }


    public void initMinuteLabel(Dimension dimension, Font font) {
        minuteLabel = new JLabel();
        minuteLabel.setText(String.format("%02d", dateModel.getMinute()) + " 分");
        minuteLabel.setPreferredSize(dimension);
        minuteLabel.setHorizontalAlignment(JLabel.CENTER);
        minuteLabel.setFont(font);
        bottomLeftPanel.add(minuteLabel);
        minuteLabel.addMouseListener(new ClickTimeLabelListener(this));
    }

    public void initSecondLabel(Dimension dimension, Font font) {
        secondLabel = new JLabel();
        secondLabel.setText(String.format("%02d", dateModel.getSecond()) + " 秒");
        secondLabel.setPreferredSize(dimension);
        secondLabel.setHorizontalAlignment(JLabel.CENTER);
        secondLabel.setFont(font);
        bottomLeftPanel.add(secondLabel);
        secondLabel.addMouseListener(new ClickTimeLabelListener(this));
    }

    public void initPanel() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(width, height));
        this.setOpaque(false);
        if (pickerMode == PickerMode.YEAR || pickerMode == PickerMode.MONTH || pickerMode == PickerMode.DAY) {
            showSelectDatePanel();
        } else {
            showSelectDateWithTimePanel();
        }
        this.setBorder(BorderFactory.createLineBorder(Colors.POPUP_BORDER, 2));
    }

    //选择日期面板
    private void showSelectDatePanel() {
        this.add(topPanel, BorderLayout.NORTH);
        this.add(selectDatePanel, BorderLayout.CENTER);
    }


    //选择日期带时间面板
    private void showSelectDateWithTimePanel() {
        this.add(topPanel, BorderLayout.NORTH);
        this.add(selectDatePanel, BorderLayout.CENTER);
        this.add(bottomPanel, BorderLayout.SOUTH);
        dateModel.addChangeListener(e -> {
            refreshTimeLabelValue();//日期变化监听刷新时间标签上的值
        });
    }

    //刷新时间标签上的值
    private void refreshTimeLabelValue() {
        if (pickerMode == PickerMode.HOUR) {
            hourLabel.setText(String.format("%02d", dateModel.getHour()) + " 时");//回写到小时标签上
        } else if (pickerMode == PickerMode.MINUTE || pickerMode == PickerMode.MINUTE_10 || pickerMode == PickerMode.MINUTE_15 || pickerMode == PickerMode.MINUTE_30) {
            hourLabel.setText(String.format("%02d", dateModel.getHour()) + " 时");//回写到小时标签上
            minuteLabel.setText(String.format("%02d", dateModel.getMinute()) + " 分");//回写到分钟标签上
        } else if (pickerMode == PickerMode.SECOND) {
            hourLabel.setText(String.format("%02d", dateModel.getHour()) + " 时");//回写到小时标签上
            minuteLabel.setText(String.format("%02d", dateModel.getMinute()) + " 分");//回写到分钟标签上
            secondLabel.setText(String.format("%02d", dateModel.getSecond()) + " 秒");//回写到秒标签上
        }
    }
}
